<title>ResourceLoadPriority tests through Service Worker</title>

<script src="resources/common.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/serviceworker/resources/test-helpers.js"></script>

<script>
window.onmessage = function(message) {
  if (message.data.hasOwnProperty('Status')) {
    window.onRequestStatusChanged(message.data['Status']);
  }
}

// This test creates a window controlled by the server worker, which makes a
// request for some subresource. The service worker intercepts the request and
// issues a fetch() for it. The service worker retrieves the priority of the
// "pass-through" fetch() request, and sends it back to this test page, where it
// is finally evaluated against expectations.
function resource_load_priority_service_worker_test(url, expected_priority,
                                                    description) {
  promise_test(t => {
    const serviceWorkerPriority = new Promise(resolve => {
      navigator.serviceWorker.onmessage = resolve;
    });

    const subresourceFinishedLoading = new Promise(resolve => {
      window.onRequestStatusChanged = e => {
        assert_equals(e, 'LOADED',
        `Resources requested in the test window ${url} loaded successfully`);
        resolve();
      }
    });

    openWindow(url, t);

    return Promise.all([serviceWorkerPriority, subresourceFinishedLoading])
      .then(promiseValues => {
        // Return the promise value associated with the service worker priority
        // event.
        return promiseValues[0];
      })
      .then(priority_event => {
        assert_not_equals(priority_event.data, 'FAILED',
          'The resource failed to load for some reason.');
        assert_equals(priority_event.data, expected_priority);
      });
  }, description);
}

promise_test(t => {
  return service_worker_unregister_and_register(t,
    'service-worker-get-priority.js', '/priorities/')
    .then(r => {
      return wait_for_state(t, r.installing, 'activated');
    });
}, 'registering service worker');

resource_load_priority_service_worker_test(
  'resources/service-worker/fetch.html', kHigh,
  'Requests from the Fetch API passing through a Service Worker should be ' +
  'loaded with kHigh priority');

resource_load_priority_service_worker_test(
  'resources/service-worker/render-blocking-stylesheet.html', kVeryHigh,
  'Render-blocking style sheets requests passing through a Service Worker ' +
  'should be loaded with kVeryHigh priority');

resource_load_priority_service_worker_test(
  'resources/service-worker/async-script.html', kLow,
  'Async scripts passing through a Service Worker should be loaded with kLow ' +
  'priority');

resource_load_priority_service_worker_test(
  'resources/service-worker/defer-script.html', kLow,
  'Deferred scripts passing through a Service Worker should be loaded with ' +
  'kLow priority');

resource_load_priority_service_worker_test(
  'resources/service-worker/module-script.html', kHigh,
  'Module scripts passing through a Service Worker should be loaded with ' +
  'kHigh priority');

resource_load_priority_service_worker_test(
  'resources/service-worker/xhr.html', kHigh,
  'XHRs passing through a Service Worker should be loaded with kHigh priority');

resource_load_priority_service_worker_test(
  'resources/service-worker/parser-blocking-script.html', kHigh,
  'Parser-blocking scripts passing through a Service Worker should be loaded ' +
  'with kHigh priority');

resource_load_priority_service_worker_test(
  'resources/service-worker/off-screen-image.html', kLow,
  'Off-screen images passing through a Service Worker should be loaded with ' +
  'kLow priority');

resource_load_priority_service_worker_test(
  'resources/service-worker/prefetch.html', kVeryLow,
  'Prefetches passing through a Service Worker should be loaded with kLowest ' +
  'priority');

// TODO(domfarolino): Add a synchronous XHR test when https://crbug.com/602051
// is resolved.

promise_test(t => {
  return service_worker_unregister(t, '/priorities/');
}, 'unregistering service worker');
</script>
